package com.growthgate.bootcommon.util;

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
 * 集合工具类
 *
 * @author GrowthGate
 * @date 2019/11/1
 */
public class CollectionUtils {

    @Contract(value = "null -> true", pure = true)
    public static boolean isEmpty(@Nullable Collection<?> c) {
        return c == null || c.isEmpty();
    }

    @Contract(value = "null -> false", pure = true)
    public static boolean isNotEmpty(@Nullable Collection<?> c) {
        return !isEmpty(c);
    }

    public static boolean isAnyEmpty(@Nullable Collection<?>... cs) {
        if (ArrayUtils.isEmpty(cs)) {
            return false;
        }
        for (Collection<?> c : Objects.requireNonNull(cs)) {
            if (isEmpty(c)) {
                return true;
            }
        }
        return false;
    }

    public static boolean isNoneEmpty(@Nullable Collection<?>... cs) {
        return !isAnyEmpty(cs);
    }

    public static boolean isAllEmpty(@Nullable Collection<?>... cs) {
        if (ArrayUtils.isEmpty(cs)) {
            return true;
        }
        for (Collection<?> c : Objects.requireNonNull(cs)) {
            if (isNotEmpty(c)) {
                return false;
            }
        }
        return true;
    }

    @Contract(value = "null -> true", pure = true)
    public static boolean isEmpty(@Nullable Map<?, ?> m) {
        return m == null || m.isEmpty();
    }

    @Contract(value = "null -> false", pure = true)
    public static boolean isNotEmpty(@Nullable Map<?, ?> m) {
        return !isEmpty(m);
    }

    public static boolean isAnyEmpty(@Nullable Map<?, ?>... ms) {
        if (ArrayUtils.isEmpty(ms)) {
            return false;
        }
        for (Map<?, ?> m : Objects.requireNonNull(ms)) {
            if (isEmpty(m)) {
                return true;
            }
        }
        return false;
    }

    public static boolean isNoneEmpty(@Nullable Map<?, ?>... ms) {
        return !isAnyEmpty(ms);
    }

    public static boolean isAllEmpty(@Nullable Map<?, ?>... ms) {
        if (ArrayUtils.isEmpty(ms)) {
            return true;
        }
        for (Map<?, ?> m : Objects.requireNonNull(ms)) {
            if (isNotEmpty(m)) {
                return false;
            }
        }
        return true;
    }

    @NotNull
    @Contract("_ -> new")
    @SafeVarargs
    public static <E> ArrayList<E> newArrayList(@Nullable E... e) {
        return e == null ? new ArrayList<>() : new ArrayList<>(Arrays.asList(e));
    }

    @NotNull
    @Contract("_ -> new")
    @SafeVarargs
    public static <E> LinkedList<E> newLinkedList(@Nullable E... e) {
        return e == null ? new LinkedList<>() : new LinkedList<>(Arrays.asList(e));
    }

    @NotNull
    @Contract("_ -> new")
    @SafeVarargs
    public static <E> HashSet<E> newHashSet(@Nullable E... e) {
        return e == null ? new HashSet<>() : new HashSet<>(Arrays.asList(e));
    }

    @NotNull
    @Contract("_ -> new")
    @SafeVarargs
    public static <E> LinkedHashSet<E> newLinkedHashSet(@Nullable E... e) {
        return e == null ? new LinkedHashSet<>() : new LinkedHashSet<>(Arrays.asList(e));
    }

    @NotNull
    @Contract("_ -> new")
    @SafeVarargs
    public static <E extends Comparable> TreeSet<E> newTreeSet(@Nullable E... e) {
        return e == null ? new TreeSet<>() : new TreeSet<>(Arrays.asList(e));
    }

    @NotNull
    @SafeVarargs
    public static <E> TreeSet<E> newTreeSet(@NotNull Comparator<E> comparator, @Nullable E... e) {
        TreeSet<E> set = new TreeSet<>(comparator);
        if (e != null) {
            set.addAll(Arrays.asList(e));
        }
        return set;
    }

    /**
     * 比较两个集合
     *
     * @param a   集合A
     * @param b   集合B
     * @param <E> 泛型
     * @return 如果集合内元素相同，返回true
     */
    public static <E> boolean equals(@NotNull Collection<E> a, @NotNull Collection<E> b) {
        return org.apache.commons.collections4.CollectionUtils.isEqualCollection(a, b);
    }

    /**
     * 取两个集合的并集
     *
     * @param a 集合a
     * @param b 集合b
     * @return 两个集合的并集
     */
    @NotNull
    public static <E> Collection<E> union(@NotNull Collection<E> a, @NotNull Collection<E> b) {
        return org.apache.commons.collections4.CollectionUtils.union(a, b);
    }

    /**
     * 取两个集合的交集
     *
     * @param a 集合a
     * @param b 集合b
     * @return 两个集合的交集
     */
    @NotNull
    public static <E> Collection<E> intersection(@NotNull Collection<E> a, @NotNull Collection<E> b) {
        return org.apache.commons.collections4.CollectionUtils.intersection(a, b);
    }

    /**
     * 取两个集合交集的补集
     *
     * @param a 集合a
     * @param b 集合b
     * @return 两个集合的补集
     */
    @NotNull
    public static <E> Collection<E> disjunction(@NotNull Collection<E> a, @NotNull Collection<E> b) {
        return org.apache.commons.collections4.CollectionUtils.disjunction(a, b);
    }

    /**
     * 取两个集合的差集
     *
     * @param a 集合a
     * @param b 集合b
     * @return 两个集合的差集
     */
    @NotNull
    @Contract("_, _ -> new")
    public static <E> Collection<E> subtract(@NotNull Collection<E> a, @NotNull Collection<E> b) {
        return org.apache.commons.collections4.CollectionUtils.subtract(a, b);
    }

}